package com.ltu.aop;


import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ltu.config.shiro.dto.UserDto;
import com.ltu.config.shiro.util.JwtUtils;
import com.ltu.domain.mp_entity.ReqLogEntity;
import com.ltu.service.ReqLogService;
import com.ltu.util.datetime.DateTimeUtil;

/**
 *
 *记录设备操作日志 
 */

@Aspect
@Component
public class UserOperateLog {
	
    private final static Logger logger = LoggerFactory.getLogger(UserOperateLog.class);

    private final static Set<String>  FilterEditor= new HashSet<String>() {{
    	add("reqLogEntity");add("get");
    	add("query");
    	add("import");
    	add("/duressAlarm/duressAlarm");
    	add("/api/room/pushStreamEventNotify");
    	add("/wxNotify");
    	add("/getOpenId");
    	add("/login");
    
    }};
   
    
    @Autowired
	   private ReqLogService reqLogService;
    //@Before的注解在方法执行之前执行
    //拦截该路径下studentList()方法，两个点表示任何参数
//    @Before("execution(public * com.example.controller.StudentController.studentList(..))")
//    public void log(){
//        System.out.println("Test before");
//    }
//
//    @After("execution(public * com.example.controller.StudentController.studentList(..))")
//    public void doAfter(){
//        System.out.println("Test after");
//    }

    @Pointcut("execution(* com.ltu.controller..*.*(..))" + "&& !execution(* com.ltu.controller.FileUploadController.*(..))"
 			+ "&& !execution(* com.ltu.controller.PayRecordController.wxNotify(..))")
     public void webLog(){}

    @Before("webLog()")
    public void doBefore(JoinPoint joinPoint) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        //url
//        logger.info("\n url:{},\n method={},\n ip={},\n class_method={},\n args={}", request.getRequestURI(), request.getMethod(), request.getRemoteAddr(), joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName(), joinPoint.getArgs());
//
//        //method
//        logger.info("\n method={}", request.getMethod());
//
//        //ip
//        logger.info("\n ip={}", request.getRemoteAddr());
//
//        //method
//        logger.info("\n class_method={}", );
//
//        //param
//        logger.info("\n args={}", joinPoint.getArgs());
        String jwtToken = request.getHeader("x-auth-token");
//        Object result = null;
       String  class_method = joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName();
        String methodName = request.getRequestURI();
        for (String filterKey : FilterEditor) {
        	if(methodName.indexOf(filterKey) > -1)
        		return;
		}
//        long startTime=DateTimeUtil.getLongStampTime();
        ReqLogEntity   reqLogEntity=new ReqLogEntity();
        
        if(joinPoint.getArgs().length>0 && (joinPoint.getArgs()[0]   instanceof HttpServletRequest || joinPoint.getArgs()[0]   instanceof HttpServletResponse))
        		return;
        String operator="_无需登录_";
        if (StringUtils.isNotBlank(jwtToken)  ) {
        	jwtToken=  StringUtils.removeStart(jwtToken, "Bearer ");
       	 	String username = JwtUtils.getUsername(jwtToken);
            UserDto user = UserDto.getUserDtoByStr(username);
             operator= user.getId().concat("_"+user.getLoginType());
        }
        	 
//        String methodName = pjd.getSignature().getDeclaringTypeName() + "." + pjd.getSignature().getName();
      
        String param=JSONArray.toJSONString(joinPoint.getArgs());
        
	        reqLogEntity.setStartTime(DateTimeUtil.getNowDate())
				        .setOprator(operator)
				        .setIp(request.getRemoteAddr() )
				        .setMethod(methodName)
				        .setParam(param)
				        .setHttpMethod(request.getMethod());
            //前置通知
        logger.info("\n=================\n \t\tIP: "+ request.getRemoteAddr()+"\n\t\t操作人: "+operator +"\n\t\t请求路径: " + methodName + " \n\t\t请求参数: " + param+"\n ================= ");
        
        
    }

//    @After("log()")
    public void doAfter() {
    }
    
//    @Around("log2()")
    public Object aroundMethod(ProceedingJoinPoint pjd) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        String jwtToken = request.getHeader("x-auth-token");
        Object result = null;
       
        String methodName = request.getRequestURI();
        long startTime=DateTimeUtil.getLongStampTime();
        ReqLogEntity   reqLogEntity=new ReqLogEntity();
        try {  
        //执行目标方法
        if(FilterEditor.contains( request.getMethod() )) 
        	return pjd.proceed();
        for (String key : FilterEditor) {
        	 if(request.getMethod().indexOf(key)>-1) {
        		 return pjd.proceed();
        	 }
			
		}
        
        if(pjd.getArgs().length>0 && (pjd.getArgs()[0]   instanceof HttpServletRequest || pjd.getArgs()[0]   instanceof HttpServletResponse))
        		return pjd.proceed();
        
        
        String operator="_无需登录_";
        if (StringUtils.isNotBlank(jwtToken)  ) {
        	jwtToken=  StringUtils.removeStart(jwtToken, "Bearer ");
       	 	String username = JwtUtils.getUsername(jwtToken);
            UserDto user = UserDto.getUserDtoByStr(username);
             operator= user.getId().concat("_"+user.getLoginType());
        }
        	 
//        String methodName = pjd.getSignature().getDeclaringTypeName() + "." + pjd.getSignature().getName();
      
        String param=JSONArray.toJSONString(pjd.getArgs());
        
	        reqLogEntity.setStartTime(DateTimeUtil.getNowDate())
				        .setOprator(operator)
				        .setIp(request.getRemoteAddr() )
				        .setMethod(methodName)
				        .setParam(param)
				        .setHttpMethod(request.getMethod());
     
            //前置通知
        	logger.info("\n请求路径: " + methodName+" \n执行方法："+request.getMethod() + " \n请求参数: " + Arrays.asList(pjd.getArgs()));
            result = pjd.proceed();
            //返回通知
            reqLogEntity.setResult(JSONObject.toJSONString(result) );
            //后置通知
            long endTime=DateTimeUtil.getLongStampTime();
            reqLogEntity.setConsumeTime(String.valueOf( endTime -  startTime));
            reqLogEntity.setEndTime(DateTimeUtil.getNowDate());
            if(!reqLogEntity.getMethod().contains("reqLogEntity") && !reqLogEntity.getMethod().contains("get")&& !reqLogEntity.getMethod().contains("query"))
            	reqLogService.save(reqLogEntity);
                       
        } catch (Throwable e) {
            //异常通知
        	logger.info("\\n请求路径:  " +" \n执行方法："+request.getMethod() +  methodName + " \n请求参数:  " + e);
        	 reqLogEntity.setResult(e.getMessage());
            throw new RuntimeException(e);
        }
        return result;
    }

//    @AfterReturning(returning = "obj", pointcut = "log()")
    public void doAfterReturnig(Object obj) {
        logger.info("reponse={}", obj);
    }
}